﻿using Inaction.Core;
using Inaction.Mapping;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace Inaction.Linq.Clause
{
    class MemberClause : WhereClause
    {
        public MemberInfo MemberInfo { get; private set; }

        IProperty p = null;

        public MemberClause(LinqRoot root, MemberExpression e)
            : base(root, e)
        {
            Type = e.Type;
            try
            {
                var val = e.GetValue();
                if (val == null)
                {
                    Left = new NullClause(root);
                }
                else if (val.GetType() == typeof(bool))
                {
                    Left = new BooleanClause(root, (bool)val);
                }
                else
                {
                    Left = new ConstantClause(root, val);
                }
                return;
            }
            catch { }
            MemberInfo = e.Member;
            if (Type.IsGenericType)
            {
                Type = Nullable.GetUnderlyingType(Type);
            }
            if (e.Expression != null)
            {
                if (e.Expression is MemberExpression)
                {
                    var member = e.Expression as MemberExpression;
                    p = ClassInfo.GetProperty(member.Expression.Type, member.Member.Name);

                    #region boolean处理
                    if (Type == typeof(bool))
                    {
                        Right = new BooleanClause(root, true);
                    }
                    #endregion

                    else if (Type == typeof(DateTime))
                    {
                        if (MemberInfo.Name == "Now")
                            Right = new ConstantClause(root, DateTime.Now);
                        if (MemberInfo.Name == "UtcNow")
                            Right = new ConstantClause(root, DateTime.UtcNow);
                        if (MemberInfo.Name == "Today")
                            Right = new ConstantClause(root, DateTime.Today);
                        if (MemberInfo.Name == "MaxValue")
                            Right = new ConstantClause(root, DateTime.MaxValue);
                        if (MemberInfo.Name == "MinValue")
                            Right = new ConstantClause(root, DateTime.MinValue);
                    }
                }
                else
                {
                    if (e.Member.MemberType == MemberTypes.Property)
                    {
                        var property = e.Member as PropertyInfo;
                        if (property.PropertyType.GetInterface(typeof(Core.ISavable).FullName) != null)
                        {

                        }
                        else
                        {
                            p = ClassInfo.GetProperty(e.Expression.Type, e.Member.Name);
                        }
                    }
                }
            }
        }
        public override string GetClauseSql()
        {
            if (p != null)
            {
                var sql = Root.FormatTableName + "." + p.Column.FormatName;
                if (Right != null)
                {
                    return sql + "=" + Right.GetClauseSql();
                }
                else return sql;
            }
            return (Left == null ? "" : Left.GetClauseSql()) + (Right == null ? "" : Right.GetClauseSql());
        }
    }
}
